﻿namespace UnityEngine
{
    using System;
    using System.Text;

    internal sealed class _AndroidJNIHelper
    {
        public static ArrayType ConvertFromJNIArray<ArrayType>(IntPtr array)
        {
            System.Type elementType = typeof(ArrayType).GetElementType();
            if (elementType.IsPrimitive)
            {
                if (elementType == typeof(int))
                {
                    return (ArrayType) AndroidJNI.FromIntArray(array);
                }
                if (elementType == typeof(bool))
                {
                    return (ArrayType) AndroidJNI.FromBooleanArray(array);
                }
                if (elementType == typeof(byte))
                {
                    return (ArrayType) AndroidJNI.FromByteArray(array);
                }
                if (elementType == typeof(short))
                {
                    return (ArrayType) AndroidJNI.FromShortArray(array);
                }
                if (elementType == typeof(long))
                {
                    return (ArrayType) AndroidJNI.FromLongArray(array);
                }
                if (elementType == typeof(float))
                {
                    return (ArrayType) AndroidJNI.FromFloatArray(array);
                }
                if (elementType == typeof(double))
                {
                    return (ArrayType) AndroidJNI.FromDoubleArray(array);
                }
                if (elementType == typeof(char))
                {
                    return (ArrayType) AndroidJNI.FromCharArray(array);
                }
            }
            else
            {
                if (elementType == typeof(string))
                {
                    IntPtr[] ptrArray = AndroidJNI.FromObjectArray(array);
                    int length = ptrArray.GetLength(0);
                    string[] strArray = new string[length];
                    for (int i = 0; i < length; i++)
                    {
                        strArray[i] = AndroidJNI.GetStringUTFChars(ptrArray[i]);
                    }
                    return (ArrayType) strArray;
                }
                if (elementType == typeof(AndroidJavaObject))
                {
                    IntPtr[] ptrArray2 = AndroidJNI.FromObjectArray(array);
                    int num3 = ptrArray2.GetLength(0);
                    AndroidJavaObject[] objArray = new AndroidJavaObject[num3];
                    for (int j = 0; j < num3; j++)
                    {
                        objArray[j] = new AndroidJavaObject(ptrArray2[j]);
                    }
                    return (ArrayType) objArray;
                }
                Debug.LogError("JNI: Unknown generic array type '" + elementType + "'");
            }
            return default(ArrayType);
        }

        public static IntPtr ConvertToJNIArray(Array array)
        {
            System.Type elementType = array.GetType().GetElementType();
            if (elementType.IsPrimitive)
            {
                if (elementType == typeof(int))
                {
                    return AndroidJNI.ToIntArray((int[]) array);
                }
                if (elementType == typeof(bool))
                {
                    return AndroidJNI.ToBooleanArray((bool[]) array);
                }
                if (elementType == typeof(byte))
                {
                    return AndroidJNI.ToByteArray((byte[]) array);
                }
                if (elementType == typeof(short))
                {
                    return AndroidJNI.ToShortArray((short[]) array);
                }
                if (elementType == typeof(long))
                {
                    return AndroidJNI.ToLongArray((long[]) array);
                }
                if (elementType == typeof(float))
                {
                    return AndroidJNI.ToFloatArray((float[]) array);
                }
                if (elementType == typeof(double))
                {
                    return AndroidJNI.ToDoubleArray((double[]) array);
                }
                if (elementType == typeof(char))
                {
                    return AndroidJNI.ToCharArray((char[]) array);
                }
            }
            else
            {
                if (elementType == typeof(string))
                {
                    string[] strArray = (string[]) array;
                    int length = array.GetLength(0);
                    IntPtr[] ptrArray = new IntPtr[length];
                    for (int i = 0; i < length; i++)
                    {
                        ptrArray[i] = AndroidJNI.NewStringUTF(strArray[i]);
                    }
                    return AndroidJNI.ToObjectArray(ptrArray);
                }
                if (elementType == typeof(AndroidJavaObject))
                {
                    AndroidJavaObject[] objArray = (AndroidJavaObject[]) array;
                    int num3 = array.GetLength(0);
                    IntPtr[] ptrArray2 = new IntPtr[num3];
                    for (int j = 0; j < num3; j++)
                    {
                        ptrArray2[j] = (objArray[j] != null) ? objArray[j].GetRawObject() : IntPtr.Zero;
                    }
                    return AndroidJNI.ToObjectArray(ptrArray2);
                }
                Debug.LogError("JNI: Unknown array type '" + elementType + "'");
            }
            return IntPtr.Zero;
        }

        public static jvalue[] CreateJNIArgArray(object[] args)
        {
            jvalue[] jvalueArray = new jvalue[args.GetLength(0)];
            int index = 0;
            foreach (object obj2 in args)
            {
                if (obj2 == null)
                {
                    jvalueArray[index].l = IntPtr.Zero;
                }
                else if (obj2.GetType().IsPrimitive)
                {
                    if (obj2 is int)
                    {
                        jvalueArray[index].i = (int) obj2;
                    }
                    else if (obj2 is bool)
                    {
                        jvalueArray[index].z = (bool) obj2;
                    }
                    else if (obj2 is byte)
                    {
                        jvalueArray[index].b = (byte) obj2;
                    }
                    else if (obj2 is short)
                    {
                        jvalueArray[index].s = (short) obj2;
                    }
                    else if (obj2 is long)
                    {
                        jvalueArray[index].j = (long) obj2;
                    }
                    else if (obj2 is float)
                    {
                        jvalueArray[index].f = (float) obj2;
                    }
                    else if (obj2 is double)
                    {
                        jvalueArray[index].d = (double) obj2;
                    }
                    else if (obj2 is char)
                    {
                        jvalueArray[index].c = (char) obj2;
                    }
                }
                else if (obj2 is string)
                {
                    jvalueArray[index].l = AndroidJNI.NewStringUTF((string) obj2);
                }
                else if (obj2 is AndroidJavaClass)
                {
                    jvalueArray[index].l = ((AndroidJavaClass) obj2).GetRawClass();
                }
                else if (obj2 is AndroidJavaObject)
                {
                    jvalueArray[index].l = ((AndroidJavaObject) obj2).GetRawObject();
                }
                else if (obj2 is Array)
                {
                    jvalueArray[index].l = ConvertToJNIArray((Array) obj2);
                }
                else if (obj2 is AndroidJavaRunnable)
                {
                    jvalueArray[index].l = AndroidJNIHelper.CreateJavaRunnable((AndroidJavaRunnable) obj2);
                }
                else
                {
                    Debug.LogError("JNI: Unknown argument type '" + obj2.GetType() + "'");
                }
                index++;
            }
            return jvalueArray;
        }

        public static IntPtr GetConstructorID(IntPtr jclass, object[] args)
        {
            string signature = GetSignature(args);
            IntPtr constructorID = AndroidJNIHelper.GetConstructorID(jclass, signature);
            if (constructorID == IntPtr.Zero)
            {
                Debug.LogError("JNI: Unable to find constructor method id with signature '" + signature + "'");
            }
            return constructorID;
        }

        public static IntPtr GetFieldID<ReturnType>(IntPtr jclass, string fieldName, bool isStatic)
        {
            string signature = GetSignature(typeof(ReturnType));
            IntPtr ptr = AndroidJNIHelper.GetFieldID(jclass, fieldName, signature, isStatic);
            if (ptr == IntPtr.Zero)
            {
                Debug.LogError("JNI: Unable to find field id for '" + fieldName + "'" + (!isStatic ? string.Empty : " (static)"));
                AndroidJNI.ExceptionClear();
            }
            return ptr;
        }

        public static IntPtr GetMethodID(IntPtr jclass, string methodName, object[] args, bool isStatic)
        {
            string signature = GetSignature(args);
            IntPtr ptr = AndroidJNIHelper.GetMethodID(jclass, methodName, signature, isStatic);
            if (ptr == IntPtr.Zero)
            {
                Debug.LogError("JNI: Unable to find method id for '" + methodName + "'" + (!isStatic ? string.Empty : " (static)"));
                AndroidJNI.ExceptionClear();
            }
            return ptr;
        }

        public static IntPtr GetMethodID<ReturnType>(IntPtr jclass, string methodName, object[] args, bool isStatic)
        {
            string signature = GetSignature<ReturnType>(args);
            IntPtr ptr = AndroidJNIHelper.GetMethodID(jclass, methodName, signature, isStatic);
            if (ptr == IntPtr.Zero)
            {
                Debug.LogError("JNI: Unable to find method id for '" + methodName + "'" + (!isStatic ? string.Empty : " (static)"));
                AndroidJNI.ExceptionClear();
            }
            return ptr;
        }

        public static string GetSignature(object obj)
        {
            if (obj == null)
            {
                return "Ljava/lang/Object;";
            }
            System.Type c = !(obj is System.Type) ? obj.GetType() : ((System.Type) obj);
            if (c.IsPrimitive)
            {
                if (c.Equals(typeof(int)))
                {
                    return "I";
                }
                if (c.Equals(typeof(bool)))
                {
                    return "Z";
                }
                if (c.Equals(typeof(byte)))
                {
                    return "B";
                }
                if (c.Equals(typeof(short)))
                {
                    return "S";
                }
                if (c.Equals(typeof(long)))
                {
                    return "J";
                }
                if (c.Equals(typeof(float)))
                {
                    return "F";
                }
                if (c.Equals(typeof(double)))
                {
                    return "D";
                }
                if (c.Equals(typeof(char)))
                {
                    return "C";
                }
            }
            else
            {
                if (c.Equals(typeof(string)))
                {
                    return "Ljava/lang/String;";
                }
                if (c.Equals(typeof(AndroidJavaRunnable)))
                {
                    return "Ljava/lang/Runnable;";
                }
                if (c.Equals(typeof(AndroidJavaClass)))
                {
                    return "Ljava/lang/Class;";
                }
                if (c.Equals(typeof(AndroidJavaObject)))
                {
                    if (obj == c)
                    {
                        return "Ljava/lang/Object;";
                    }
                    AndroidJavaObject obj3 = ((AndroidJavaObject) obj).Call<AndroidJavaObject>("getClass", new object[0]);
                    return ("L" + obj3.Call<string>("getName", new object[0]) + ";");
                }
                if (typeof(Array).IsAssignableFrom(c))
                {
                    if (c.GetArrayRank() != 1)
                    {
                        Debug.LogError("JNI: System.Array in n dimensions is not allowed");
                        return string.Empty;
                    }
                    StringBuilder builder = new StringBuilder();
                    builder.Append('[');
                    builder.Append(GetSignature(c.GetElementType()));
                    return builder.ToString();
                }
                Debug.LogError(string.Concat(new object[] { "JNI: Unknown signature for type '", c, "' (obj = ", obj, ") ", (c != obj) ? "instance" : "equal" }));
            }
            return string.Empty;
        }

        public static string GetSignature(object[] args)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append('(');
            foreach (object obj2 in args)
            {
                builder.Append(GetSignature(obj2));
            }
            builder.Append(")V");
            return builder.ToString();
        }

        public static string GetSignature<ReturnType>(object[] args)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append('(');
            foreach (object obj2 in args)
            {
                builder.Append(GetSignature(obj2));
            }
            builder.Append(')');
            builder.Append(GetSignature(typeof(ReturnType)));
            return builder.ToString();
        }
    }
}

